package clienteServidor;

import java.io.Serializable;
import java.net.SocketException;
import java.net.UnknownHostException;

import sensorLAN.utiles.Fecha;
import sensorLAN.utiles.Numeros;
import clienteServidor.excepciones.ImposibleObtenerDatosEquipoException;
import clienteServidor.excepciones.ImposibleObtenerIPException;
import clienteServidor.infoHWSWEquipo.Bateria;
import clienteServidor.infoHWSWEquipo.CPU;
import clienteServidor.infoHWSWEquipo.Memoria;
import clienteServidor.infoHWSWEquipo.Red;

public class DatosEquipo implements Serializable, Comparable<DatosEquipo>{

	private static final long serialVersionUID = 5256947320917872831L;

	//valores obligatorios
	private String mac;
	private String ip;
	private String broadcast;
	private String nombreEquipo;
	private String usuario;
	
	//infoRed
	private String mascara;
	private String red;
	
	//infoSO
	private String sistemaOperativo;
	private String arquitecturaSO;
	private String versionSO;
	private String javaVersion;
	private String javaNombreVM;
	
	//InfoSistema
	private Bateria bateria;
	private int memoriaLibre, memoriaTotal;
	private float usoCpu;
	
	//otros valores que son cambiantes, pero en algun momento obligatorios
	private boolean conectadoALan;	
	private long marcaTiempoCreacion, marcaTiempoRecepcion;	
	private int versionCliente;
	private OrdenesServidor ordenesServidor;
	
	public DatosEquipo() throws ImposibleObtenerIPException{
		this(0, new OrdenesServidor());
	}
	
	public DatosEquipo(int versionCliente, OrdenesServidor ordenesServidor) throws ImposibleObtenerIPException{
		this.ordenesServidor= ordenesServidor;
		this.setVersionCliente(versionCliente);
		try {
			this.infoObligatoria();
			this.infoSO();			
			this.infoRed();			
			this.infoSistema();
			
			this.setConectadoALan(true);			
			this.setMarcaTiempoCreacion(Fecha.getMarcaTiempo());			
			this.setMarcaTiempoRecepcion(0);
		} catch (Exception e) {
			e.printStackTrace();
			throw new ImposibleObtenerDatosEquipoException();
		}
	}
	
	private void infoObligatoria() throws SocketException, UnknownHostException, ImposibleObtenerIPException {
		this.setMac(Red.getInstancia().getMac());
		this.setIp(Red.getInstancia().getIpV4());
		this.setBroadcast(Red.getInstancia().getBroadcast());
		this.setNombreEquipo(Red.getInstancia().getNombreEquipo());
		this.setUsuario(System.getProperty("user.name"));
	}

	private void infoSistema(){
		if(ordenesServidor.isInfoCPU()){	
			this.setMemoriaLibre((int) Memoria.getMemoriaLibreMB());			
			this.setMemoriaTotal((int) Memoria.getMemoriaTotalMB());			
			double valorCPU= CPU.getInstancia().getPorcentajeUsoCPU100();			
			this.setUsoCpu((float) Numeros.redondear(valorCPU, 2));
		}else{
			this.setMemoriaLibre(0);			
			this.setMemoriaTotal(0);			
			this.setUsoCpu(0.0f);
		}
		if(ordenesServidor.isInfoBateria()){
			this.bateria= new Bateria();
		}
	}
	
	private void infoSO(){
		if(ordenesServidor.isInfoSO()){
			this.setSistemaOperativo(System.getProperty("os.name"));			
			this.setArquitecturaSO(System.getProperty("os.arch"));			
			this.setVersionSO(System.getProperty("os.version"));			
			this.setJavaVersion(System.getProperty("java.version"));			
			this.setJavaNombreVM(System.getProperty("java.vm.name"));
		}else{		
			this.setSistemaOperativo("");			
			this.setArquitecturaSO("");			
			this.setVersionSO("");			
			this.setJavaVersion("");			
			this.setJavaNombreVM("");
		}		
	}
	
	private void infoRed() throws UnknownHostException, SocketException, ImposibleObtenerIPException{
		if(ordenesServidor.isInfoRed()){
			this.setMascara(Red.getInstancia().getMascara());
			this.setRed(Red.getInstancia().getRed());
		}else{
			this.setMascara("0.0.0.0");
			this.setRed("0.0.0.0");
		}
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((mac == null) ? 0 : mac.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		DatosEquipo other = (DatosEquipo) obj;
		if (mac == null) {
			if (other.mac != null)
				return false;
		} else if (!mac.equals(other.mac))
			return false;
		return true;
	}

	public String getIp() {
		return ip;
	}

	public String getMascara() {
		return mascara;
	}

	public String getRed() {
		return red;
	}

	public String getBroadcast() {
		return broadcast;
	}

	public String getMac() {
		return mac;
	}

	public String getUsuario() {
		return usuario;
	}

	public String getNombreEquipo() {
		return nombreEquipo;
	}

	public String getSistemaOperativo() {
		return sistemaOperativo;
	}

	public String getArquitecturaSO() {
		return arquitecturaSO;
	}

	public String getVersionSO() {
		return versionSO;
	}

	public boolean isConectadoALan() {
		return conectadoALan;
	}

	protected void setIp(String ip) {
		this.ip = ip;
	}

	protected void setMascara(String mascara) {
		this.mascara = mascara;
	}

	protected void setRed(String red) {
		this.red = red;
	}

	protected void setBroadcast(String broadcast) {
		this.broadcast = broadcast;
	}

	protected void setMac(String mac) {
		this.mac = mac;
	}

	protected void setUsuario(String usuario) {
		this.usuario = usuario;
	}

	protected void setNombreEquipo(String nombreEquipo) {
		this.nombreEquipo = nombreEquipo;
	}

	protected void setSistemaOperativo(String sistemaOperativo) {
		this.sistemaOperativo = sistemaOperativo;
	}

	protected void setArquitecturaSO(String arquitecturaSO) {
		this.arquitecturaSO = arquitecturaSO;
	}

	protected void setVersionSO(String versionSO) {
		this.versionSO = versionSO;
	}

	public void setConectadoALan(boolean conectadoALan) {
		this.conectadoALan = conectadoALan;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}
	
	public String getEstadoBateria() {
		if(ordenesServidor.isInfoBateria() && conectadoALan) return this.bateria.getEstadoBateria();
		else return Bateria.DESCONOCIDO;
	}
	
	public String getDetalleBateria() {
		if(ordenesServidor.isInfoBateria() && conectadoALan) return this.bateria.getDetalleBateria();
		else return Bateria.DESCONOCIDO;
	}
	
	public String getPorcentajeBateria() {
		if(ordenesServidor.isInfoBateria() && conectadoALan) return this.bateria.getPorcentajeBateria();
		else return Bateria.DESCONOCIDO;
	}

	public long getMarcaTiempoCreacion() {
		return marcaTiempoCreacion;
	}

	protected void setMarcaTiempoCreacion(long marcaTiempoCreacion) {
		this.marcaTiempoCreacion = marcaTiempoCreacion;
	}

	public long getMarcaTiempoRecepcion() {
		return marcaTiempoRecepcion;
	}

	public void setMarcaTiempoRecepcion(long marcaTiempoRecepcion) {
		this.marcaTiempoRecepcion = marcaTiempoRecepcion;
	}

	public int getVersionCliente() {
		return versionCliente;
	}

	protected void setVersionCliente(int versionCliente) {
		this.versionCliente = versionCliente;
	}

	public int getMemoriaLibre() {
		return memoriaLibre;
	}

	protected void setMemoriaLibre(int memoriaLibre) {
		this.memoriaLibre = memoriaLibre;
	}

	public int getMemoriaTotal() {
		return memoriaTotal;
	}

	protected void setMemoriaTotal(int memoriaTotal) {
		this.memoriaTotal = memoriaTotal;
	}

	public float getUsoCpu() {
		return usoCpu;
	}

	protected void setUsoCpu(float usoCpu) {
		this.usoCpu = usoCpu;
	}

	@Override
	public int compareTo(DatosEquipo de) {
		return this.getUsuario().compareTo(de.getUsuario());
	}	
	
	public String getJavaVersion() {
		return javaVersion;
	}

	protected void setJavaVersion(String javaversion) {
		this.javaVersion = javaversion;
	}

	public String getJavaNombreVM() {
		return javaNombreVM;
	}

	protected void setJavaNombreVM(String javaNombreVM) {
		this.javaNombreVM = javaNombreVM;
	}

	@Override
	public String toString() {
		return "DatosEquipo [ip=" + ip + ", mascara=" + mascara + ", red="
				+ red + ", broadcast=" + broadcast + ", mac=" + mac
				+ ", usuario=" + usuario + ", nombreEquipo=" + nombreEquipo
				+ ", sistemaOperativo=" + sistemaOperativo
				+ ", arquitecturaSO=" + arquitecturaSO + ", versionSO="
				+ versionSO + ", javaVersion=" + javaVersion
				+ ", javaNombreVM=" + javaNombreVM + ", bateria=" + bateria
				+ ", memoriaLibre=" + memoriaLibre + ", memoriaTotal="
				+ memoriaTotal + ", usoCpu=" + usoCpu + ", conectadoALan="
				+ conectadoALan + ", marcaTiempoCreacion="
				+ marcaTiempoCreacion + ", marcaTiempoRecepcion="
				+ marcaTiempoRecepcion + ", versionCliente=" + versionCliente
				+ ", getEstadoBateria()=" + getEstadoBateria()
				+ ", getDetalleBateria()=" + getDetalleBateria()
				+ ", getPorcentajeBateria()=" + getPorcentajeBateria() + "]";
	}

	public static void main(String[] args) {
		try {
			System.out.println(new DatosEquipo(0, new OrdenesServidor()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
